kind: GCPClusterConfiguration
apiVersions:
- apiVersion: deckhouse.io/v1
  openAPISpec:
    type: object
    description: |
      Describes the configuration of a cloud cluster in GCP.

      Used by the cloud provider if a cluster's control plane is hosted in the cloud.

      Run the following command to change the configuration in a running cluster:

      ```shell
      kubectl -n d8-system exec -ti deploy/deckhouse -- deckhouse-controller edit provider-cluster-configuration
      ```
    x-doc-search: |
      ProviderClusterConfiguration
    x-unsafe-rules: [deleteZones]
    x-examples:
      - apiVersion: deckhouse.io/v1
        kind: GCPClusterConfiguration
        layout: WithoutNAT
        sshKey: "<SSH_PUBLIC_KEY>"
        subnetworkCIDR: 10.36.0.0/24
        masterNodeGroup:
          replicas: 1
          zones:
            - europe-west3-b
          instanceClass:
            machineType: n1-standard-4
            image: projects/ubuntu-os-cloud/global/images/ubuntu-2204-jammy-v20220831
            diskSizeGb: 20
        nodeGroups:
          - name: static
            replicas: 1
            zones:
              - europe-west3-b
            instanceClass:
              machineType: n1-standard-4
              image: projects/ubuntu-os-cloud/global/images/ubuntu-2204-jammy-v20220831
              diskSizeGb: 20
              additionalNetworkTags:
                - tag1
              additionalLabels:
                kube-node: static
        provider:
          region: europe-west3
          serviceAccountJSON: "<SERVICE_ACCOUNT_JSON>"
    additionalProperties: false
    required: [apiVersion, kind, layout, provider, masterNodeGroup, sshKey]
    properties:
      apiVersion:
        type: string
        enum: [deckhouse.io/v1, deckhouse.io/v1alpha1]
      kind:
        type: string
        enum: [GCPClusterConfiguration]
      subnetworkCIDR:
        type: string
        pattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(3[0-2]|[1-2][0-9]|[0-9]))$'
        description: A subnet to use for cluster nodes.
        x-unsafe: true
      sshKey:
        type: string
        description: A public key to access nodes as `user`.
      sshAllowList:
        type: array
        items:
          type: string
        description: |
          A list of CIDR's allowed to connect to nodes via SSH.

          By default, from any.
      labels:
        type: object
        description: |
          A list of labels to attach to cluster resources.

          Note that you have to re-create all the machines to add new tags if tags were modified in the running cluster.

          You can learn more about the labels in the [official documentation](https://cloud.google.com/resource-manager/docs/creating-managing-labels).

          Format — `key: value`.
        additionalProperties:
          type: string
      peeredVPCs:
        type: array
        description: |
          A list of GCP VPC networks to peer with the cluster network.

          The service account must have access to all the VPCs listed. You have to configure the peering connection [manually](https://cloud.google.com/vpc/docs/using-vpc-peering#gcloud) if no access is available.
        items:
          type: string
      masterNodeGroup:
        type: object
        required: [replicas, instanceClass]
        description: |
          Parameters of the master's NodeGroup.

          > Caution! After changing the parameters of the section, you need to run `dhctl converge` for the changes to take effect.
        properties:
          replicas:
            type: integer
            minimum: 1
            description: |
              The number of master nodes to create.

              It is important to have an odd number of masters to ensure a quorum.
            x-unsafe-rules: [updateReplicas]
          additionalNetworkTags:
            description: |
              The list of additional tags.

              For example, you can use tags to apply firewall rules to instances. The detailed description of network tags is available in the [official documentation](https://cloud.google.com/vpc/docs/add-remove-network-tags).
            type: array
            items:
              type: string
          additionalLabels:
            type: object
            description: |
              Additional labels.

              [More info...](https://cloud.google.com/resource-manager/docs/creating-managing-labels).
            x-doc-example: |
              ```yaml
              project: cms-production
              severity: critical
              ```
            additionalProperties:
              type: string
          instanceClass:
            type: object
            required: [machineType, image]
            description: Partial contents of the [GCPInstanceClass](https://deckhouse.io/documentation/v1/modules/030-cloud-provider-gcp/cr.html#gcpinstanceclass) fields.
            properties:
              machineType: &instanceClassMachineType
                type: string
                example: n1-standard-4
                description: |
                  Machine type of GCP instance.

                  > **Caution!** Make sure that this type is present in all zones specified in the `zones` parameter.

                  GCP [lets you](https://cloud.google.com/compute/docs/instances/creating-instance-with-custom-machine-type#create) specify a custom amount of resources (CPU and RAM), e.g., `custom-8-40960` or `n2-custom-8-40960`.
              image: &instanceClassImage
                type: string
                example: projects/ubuntu-os-cloud/global/images/ubuntu-1804-bionic-v20190911
                description: |
                  Image to use while provisioning GCP servers.

                  You can find a list of available images in the [provider documentation](https://cloud.google.com/compute/docs/images#ubuntu).

                  The list of OS and their versions supported by Deckhouse can be found in the [Deckhouse documentation](https://deckhouse.ru/documentation/v1/supported_versions.html) (take into account the Deckhouse version used).
              diskSizeGb: &instanceClassDiskSizeGb
                description: Instance disk size in gibibytes.
                example: 20
                type: integer
              etcdDiskSizeGb:
                description: Etcd disk size in gibibytes.
                example: 20
                default: 20
                type: integer
              disableExternalIP: &instanceClassDisableExternalIP
                type: boolean
                enum: [true, false]
                x-doc-default: true
                description: |
                  Defines whether to disable external IP for an instance or not.

                  This parameter is only available for the `Standard` layout.

                  True means that nodes do not have public addresses and connect to the Internet over `CloudNAT`;

                  False means that static public addresses are created for nodes, they are also used for One-to-one NAT.;
          zones:
            type: array
            description: A limited set of zones in which nodes can be created.
            items:
              type: string
            minItems: 1
            uniqueItems: true
      nodeGroups:
        description: |
          An array of additional NodeGroups for creating static nodes (e.g., for dedicated front nodes or gateways).
        type: array
        items:
          type: object
          required: [name, replicas, instanceClass]
          properties:
            name:
              type: string
              description: The name of the NodeGroup to use for generating node names.
            replicas:
              type: integer
              description: The number of nodes to create.
            nodeTemplate:
              type: object
              description: Parameters of Node objects in Kubernetes to add after registering the node.
              properties:
                labels:
                  type: object
                  description: The same as the `metadata.labels` standard (https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta).
                  additionalProperties:
                    type: string
                annotations:
                  type: object
                  description: The same as the `metadata.annotations` (https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta).
                  additionalProperties:
                    type: string
                taints:
                  type: array
                  description: The same as the `.spec.taints` field of the Node object(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#taint-v1-core). **CAUTION!** Only the `effect`, `key`, `values` fields are available
                  items:
                    type: object
                    properties:
                      effect:
                        type: string
                        enum: [NoSchedule, PreferNoSchedule, NoExecute]
                      key:
                        type: string
                      value:
                        type: string
            additionalNetworkTags:
              type: array
              items:
                type: string
            additionalLabels:
              type: object
              additionalProperties:
                type: string
            instanceClass:
              required: [machineType, image]
              type: object
              description: Partial contents of the [GCPInstanceClass](https://deckhouse.io/documentation/v1/modules/030-cloud-provider-gcp/cr.html#gcpinstanceclass) fields.
              properties:
                machineType: *instanceClassMachineType
                image: *instanceClassImage
                diskSizeGb: *instanceClassDiskSizeGb
                disableExternalIP: *instanceClassDisableExternalIP
            zones:
              type: array
              description: A limited set of zones in which nodes can be created.
              items:
                type: string
              minItems: 1
              uniqueItems: true
      layout:
        type: string
        enum: [Standard, WithoutNAT]
        description: |
          The way resources are located in the cloud.

          `Standard` - set [Cloud NAT](https://cloud.google.com/nat/docs/overview#benefits) mode. [More info...](https://deckhouse.io/documentation/v1/modules/030-cloud-provider-gcp/layouts.html#standard)

          `WithoutNAT` - a dedicated VPC is created for the cluster. All cluster nodes have public IP addresses. [More info...](https://deckhouse.io/documentation/v1/modules/030-cloud-provider-gcp/layouts.html#withoutnat)
        x-unsafe: true
      standard:
        type: object
        description: Settings for the `Standard` layout.
        additionalProperties: false
        required: []
        properties:
          cloudNATAddresses:
            type: array
            description: A list of public static IP addresses for `Cloud NAT`.
            items:
              type: string
      withoutNAT:
        description: Settings for the `WithoutNAT` layout.
        type: object
        additionalProperties: false
        required: []
        properties: {}
      provider:
        type: object
        additionalProperties: false
        description: Parameters for connecting to the GCP API.
        required: [region, serviceAccountJSON]
        properties:
          region:
            type: string
            description: The name of the region where instances will be provisioned.
            x-unsafe: true
          serviceAccountJSON:
            type: string
            description: |
              A key to the Service Account with Project Admin privileges (`service account key`) in the JSON format.

              [How to create it](https://cloud.google.com/iam/docs/creating-managing-service-account-keys#creating_service_account_keys) a `service account key`.
      zones:
        type: array
        description: A limited set of zones in which nodes can be created.
        items:
          type: string
        minItems: 1
        uniqueItems: true
    oneOf:
    - required: [layout]
      properties:
        layout:
          enum: [Standard]
    - required: [layout]
      properties:
        layout:
          enum: [WithoutNAT]
        masterNodeGroup:
          properties:
            instanceClass:
              type: object
              properties:
                disableExternalIP:
                  enum: [false]
        nodeGroups:
          type: array
          items:
            type: object
            properties:
              instanceClass:
                type: object
                properties:
                  disableExternalIP:
                    type: boolean
                    enum: [false]
